﻿using System.Collections.Generic;
using Netfraction.Common;

namespace NetfractionHub.Network.Protocol.BASE.Handler
{
    public class HandlerPAS : ProtocolMessageActionHandler
    {
        public HandlerPAS()
            : base()
        {
            mSupportedConnectionStates = new List<RemoteMachine.ConnectionState>();
        }

        #region ProtocolMessageActionHandler Members

        public override string ProtocolActionCode
        {
            get { return "PAS"; }
        }

        public override bool HandleProtocolMessage(NetfractionHub.RemoteMachine.Node node, ProtocolMessage message, IEnumerable<ProtocolFeature> extenders)
        {
            if (message.Parameters.Count == 1 && message.MessageType == ProtocolMessage.MessageTypeEnum.Hub)
            {
                string encodedPassword = message.Parameters[0].ParameterValue;
                if (encodedPassword.Length > 0)
                {
                    node.SessionHashAlgorithm.Initialize();

                    byte[] pass = System.Text.Encoding.UTF8.GetBytes(node.SecurityIdentity.Password);
                    byte[] saltedPass = new byte[pass.Length + node.Identity.PasswordSaltBytes.Length];
                    System.Buffer.BlockCopy(pass, 0, saltedPass, 0, pass.Length);
                    System.Buffer.BlockCopy(node.Identity.PasswordSaltBytes, 0, saltedPass, pass.Length, node.Identity.PasswordSaltBytes.Length);
                    
                    byte[] hashedPass = node.SessionHashAlgorithm.ComputeHash(saltedPass);
                    bool checkSuccess = encodedPassword == Base32.Encode(hashedPass).Substring(0, 39);

                    if (checkSuccess)
                    {
                        ConnectionManager.OnClientConnectSuccess(node);
                        return true;
                    }
                    else
                    {
                        ConnectionManager.SendStatusMessageToNode(node, Factory.FactorySTA.StatusSeverity.FatalError, Factory.FactorySTA.StatusErrorCode.InvalidPassword);
                        ConnectionManager.DisconnectNode(node);
                        return false;
                    }
                }
            }
            return false;
        }

        #endregion
    }
}
